package org.zjx.factory;

import org.zjx.db.ScreenDB;
import org.zjx.entity.Location;
import org.zjx.entity.Sects;
import org.zjx.entity.Transfer;
import org.zjx.model.route.*;
import org.zjx.pojo.RouteQueryPojo;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 路由工厂完整实现
 * 负责创建所有类型的路由对象
 */
public class RouteFactoryImpl implements RouteFactory {

    // ---------- 基础路由创建 ----------

    @Override
    public Route createFromTransfer(Transfer transfer) {
        switch (transfer.getType()) {
            case SCENE_TRANSFER:
                return new SceneTransferRoute(
                        transfer.getStartLocation(),
                        transfer.getEndLocation(),
                        transfer.getClickX(),
                        transfer.getClickY());
            case NPC_TRANSFER:
                return new NpcTransferRoute(
                        transfer.getStartLocation(),
                        transfer.getEndLocation(),
                        transfer.getClickX(),
                        transfer.getClickY(),
                        transfer.getDialogues());
            case ROOM_ENTER:
                return new RoomEnterRoute(
                        transfer.getStartLocation(),
                        transfer.getEndLocation(),
                        transfer.getClickX(),
                        transfer.getClickY());
            case ROOM_EXIT:
                return new RoomExitRoute(
                        transfer.getStartLocation(),
                        transfer.getEndLocation(),
                        transfer.getClickX(),
                        transfer.getClickY());
            default:
                throw new IllegalArgumentException("不支持的传送类型: " + transfer.getType());
        }
    }

    @Override
    public Route createRunningRoute(Location start, Location end, boolean indoor) {
        return new RunningRoute(start, end, indoor);
    }

    // ---------- 玩家路由生成 ----------

    @Override
    public List<Route> createPlayerRoutes(RouteQueryPojo routeQueryPojo) {
        List<Route> routes = new ArrayList<>();

        // 1. 飞行符路由
        addFlyingCharmRoutes(routeQueryPojo, routes);

        // 2. 合成旗路由
        addFlyingFlagRoutes(routeQueryPojo, routes);

        // 3. 法宝路由
        addMagicItemRoutes(routeQueryPojo, routes);

        // 4. 回师门技能
        addSectRoutes(routeQueryPojo, routes);

        // 5. 自定义路由
        addCustomRoutes(routeQueryPojo, routes);

        return routes;
    }

    // ---------- 私有辅助方法 ----------

    private void addFlyingCharmRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        if (!routeQueryPojo.isHasFlyingCharm()) return;

        FlyingCharmRoute.DESTINATIONS.forEach((city, loc) -> {
            if (!routeQueryPojo.getStart().getCity().equals(city)) {
                routes.add(new FlyingCharmRoute(
                        routeQueryPojo.getStart().toLocation(),
                        city
                ));
            }
        });
    }

    private void addFlyingFlagRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        Map<String, List<Point>> map = routeQueryPojo.getFlyingFlagsPoints();
        if (map == null || map.isEmpty()) return;
        for (Map.Entry<String, List<Point>> entry : map.entrySet()) {
            String city = entry.getKey();
            List<Point> points = entry.getValue();
            points.forEach(point -> {
                Location location = new Location(new ScreenDB().findByName(city), point.x, point.y);

                routes.add(new FlyingFlagRoute(
                        routeQueryPojo.getStart().toLocation(),
                        location
                ));
            });
        }
    }

    private void addMagicItemRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        //TODO 法宝未写
    }

    private void addSectRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        if (routeQueryPojo.isInTeam()) return;
        Sects sects = routeQueryPojo.getSects();
        if (sects.getName() != null) {
            Location dest = new Location(new ScreenDB().findByName(sects.getF8Location().getCity()), sects.getF8Location().getX(), sects.getF8Location().getY());

            if (routeQueryPojo.getStart().toLocation().isNear(dest)) return;

            routes.add(new BackToSectRoute(
                    routeQueryPojo.getStart().toLocation(),
                    dest,
                    sects.getName()
            ));
        }
    }

    private void addCustomRoutes(RouteQueryPojo routeQueryPojo, List<Route> routes) {
        Map<String, List<Point>> map = routeQueryPojo.getFlyingFlagsPoints();
        if (map == null || map.isEmpty()) return;
        for (Map.Entry<String, List<Point>> entry : map.entrySet()) {
            String city = entry.getKey();
            List<Point> points = entry.getValue();
            points.forEach(point -> {
                Location location = new Location(new ScreenDB().findByName(city), point.x, point.y);

                routes.add(new FlyingFlagRoute(
                        routeQueryPojo.getStart().toLocation(),
                        location
                ));
            });
        }
    }
}